﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Godot.core
{
    public abstract class ScriptInstance 
    {
        public abstract bool set(StringName p_name, Variant p_value);
	    
        public abstract bool get(StringName p_name, ref Variant r_ret);
	    
        public abstract void get_property_list(List<PropertyInfo> p_properties);

	    public abstract void get_method_list(ref List<MethodInfo> p_list);

	    public abstract bool has_method(StringName p_method);

        public virtual Variant call(StringName p_method, Variant p_arg1 = null, Variant p_arg2 = null, Variant p_arg3 = null, Variant p_arg4 = null, Variant p_arg5 = null)
        {
            List<Variant> args = new List<Variant>(){ p_arg1, p_arg2, p_arg3, p_arg4, p_arg5 };

	        for(int i = 0; i < args.Count; i++) 
            {
                if (args[i] == null ? true : args[i].type == Variant.Type.NIL)
                {
                    args.RemoveRange(i, args.Count);
                    break;
                }
	        }

            Variant.CallError error = new Variant.CallError();
	        return call(p_method, args.ToArray(), error);
        }
	        
        public abstract Variant call(StringName p_method, Variant[] p_args, Variant.CallError r_error);
	        
        public virtual void call_multilevel(StringName p_method,  Variant p_arg1 = null, Variant p_arg2 = null, Variant p_arg3 = null, Variant p_arg4 = null, Variant p_arg5 = null)
        {
            call(p_method, p_arg1, p_arg2, p_arg3, p_arg4, p_arg5);
        }
	        
        public virtual void call_multilevel(StringName p_method, Variant[] p_args)
        {
            Variant.CallError error = new Variant.CallError();
            call(p_method, p_args, error);
        }

	    public virtual void call_multilevel_reversed(StringName p_method, Variant[] p_args)
        {
            Variant.CallError error = new Variant.CallError();
            call(p_method, p_args, error);
        }

	    public abstract void notification(int p_notification);

	    public abstract Script script { get; }

        public abstract ScriptLanguage language { get; }
    }
}
